package controller

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"io/ioutil"
	"net/http"
	"tone-agent/core"
	"tone-agent/entity"
)

func SendTaskController(c *gin.Context) {
	checkAgentMode(c)
	task := entity.Task{}
	data, _ := ioutil.ReadAll(c.Request.Body)
	json.Unmarshal(data, &task)
	core.MyLogger.WithFields(core.LogFields{
		"tid": 	   task.Tid,
		"sync":    task.Sync,
		"args":    task.Args,
		"timeout": task.Timeout,
		// "script":  task.Script,
	}).Info("Send-task-request from toneagent-proxy")
	if task.Sync {
		taskResult := core.ExecTask(task)
		core.RemoveResult(task.Tid)
		c.JSON(http.StatusOK, gin.H{
			"SUCCESS":     entity.ResponseOk,
			"TID":         task.Tid,
			"STATUS":      entity.TaskCompletedStatus,
			"TASK_RESULT": taskResult["result"],
			"TASK_PID":    taskResult["task_pid"],
			"ERROR_CODE":  taskResult["error_code"],
			"ERROR_MSG":   taskResult["error_msg"],
			"EXIT_CODE":   taskResult["exit_code"],
			"FINISH_TIME": taskResult["finish_time"],
		})
	} else {
		go core.ExecTask(task)
		c.JSON(http.StatusOK, gin.H{
			"SUCCESS": entity.ResponseOk,
			"TID":     task.Tid,
			"STATUS":  entity.TaskRunningStatus,
		})
	}
}

func QueryTaskController(c *gin.Context) {
	checkAgentMode(c)
	tid := c.Query("tid")
	taskResult, _ := core.ReadResult(tid)
	if taskResult != nil {
		if taskResult["status"] == entity.TaskCompletedStatus {
			core.MyLogger.WithFields(core.LogFields{
				"tid":    tid,
				"result": taskResult,
				"from":   c.Request.Host,
			}).Info("Query-task-request from toneagent-proxy, task completed!")
			core.RemoveResult(tid)
		}
		c.JSON(http.StatusOK, gin.H{
			"SUCCESS":     entity.ResponseOk,
			"TID":         tid,
			"TASK_STATUS": taskResult["status"],
			"TASK_RESULT": taskResult["result"],
			"TASK_PID":    taskResult["task_pid"],
			"ERROR_CODE":  taskResult["error_code"],
			"ERROR_MSG":   taskResult["error_msg"],
			"EXIT_CODE":   taskResult["exit_code"],
			"FINISH_TIME": taskResult["finish_time"],
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"SUCCESS":     entity.ResponseOk,
			"TID":         tid,
			"TASK_STATUS": entity.TaskRunningStatus,
		})
	}
}

func HeartbeatController(c *gin.Context) {
	checkAgentMode(c)
	core.MyLogger.WithFields(core.LogFields{"from": c.Request.Host}).Info(
		"Heartbeat-request from toneagent-proxy")
	response := gin.H{
		"SUCCESS": entity.ResponseOk,
		"ARCH":    core.ExecCommand("arch"),
		"KERNEL":  core.ExecCommand("uname", "-r"),
		"DISTRO":  core.ExecCommand("cat", "/etc/os-release"),
	}
	c.JSON(http.StatusOK, response)
}

func checkAgentMode(c *gin.Context) {
	if viper.GetString(entity.Mode) == entity.ActiveMode {
		core.MyLogger.WithFields(core.LogFields{"from": c.Request.Host}).Warning(
			"This agent is in active mode, but a request was received")
		c.JSON(http.StatusOK, gin.H{
			"SUCCESS": entity.ResponseFail,
			"ERROR":   "This agent is in active mode and does not support invoking this interface",
		})
	}
}
